import {
  TableOptions,
  TableAPI,
  Column,
  RowData,
  CellValue,
  CellPosition,
  CellRange,
  EventType,
  EventHandler,
  CellChangeEvent,
  SelectionChangeEvent,
  SelectionMode
} from '../types'
import { DataManager } from '../data/DataManager'
import { VirtualScrollManager } from '../virtual-scroll/VirtualScrollManager'
import { TableRenderer } from '../renderer/TableRenderer'
import { EventManager } from '../events/EventManager'
import { ContextMenu } from '../ui/ContextMenu'
import { editorFactory } from '../editors'
import type { CellEditor } from '../types'

// 默认配置
const DEFAULT_OPTIONS: Partial<TableOptions> = {
  width: 800,
  height: 600,
  rowHeight: 30,
  headerHeight: 35,
  showRowNumber: true,
  showGridLines: true,
  editable: true,
  multiSelect: true,
  columnResize: true,
  keyboardNavigation: true,
  copyPaste: true,
  undoRedo: true,
  virtualScroll: true
}

export class CanvasTable implements TableAPI {
  private container: HTMLElement
  private canvas: HTMLCanvasElement
  private columns: Column[]
  private options: Required<TableOptions>
  
  // 核心模块
  private dataManager: DataManager
  private scrollManager: VirtualScrollManager
  private renderer: TableRenderer
  private eventManager: EventManager
  private contextMenu: ContextMenu | null = null
  
  // 状态
  private _isDestroyed: boolean = false
  private editingCell: CellPosition | null = null
  private editor: HTMLElement | null = null
  private currentEditor: CellEditor | null = null
  private resizeObserver: ResizeObserver | null = null

  // 事件处理器映射
  private eventHandlers: Map<EventType, Set<EventHandler>> = new Map()
  
  // 保存当前的排序配置（用于远程排序）
  private currentSortConfig: { column: string | null; direction: 'asc' | 'desc' | null } = {
    column: null,
    direction: null
  }

  constructor(
    container: HTMLElement,
    columns: Column[],
    options?: TableOptions
  ) {
    this.container = container
    this.columns = columns
    this.options = { ...DEFAULT_OPTIONS, ...options } as Required<TableOptions>
    
    // 设置容器样式，防止内容溢出
    this.container.style.position = 'relative'
    this.container.style.overflow = 'hidden'
    
    // 如果容器没有明确的尺寸，设置一个默认尺寸
    const containerStyle = window.getComputedStyle(this.container)
    if (!this.container.style.width && containerStyle.width === 'auto') {
      this.container.style.width = `${this.options.width}px`
    }
    if (!this.container.style.height && containerStyle.height === 'auto') {
      this.container.style.height = `${this.options.height}px`
    }
    
    // 创建画布
    this.canvas = this.createCanvas()
    
    // 获取容器的实际尺寸
    const rect = this.container.getBoundingClientRect()
    const containerWidth = rect.width || this.options.width
    const containerHeight = rect.height || this.options.height
    
    // 初始化模块
    this.dataManager = new DataManager(columns)
    
    this.scrollManager = new VirtualScrollManager({
      containerWidth: containerWidth,
      containerHeight: containerHeight,
      rowHeight: this.options.rowHeight,
      headerHeight: this.options.headerHeight
    })
    
    // 设置行号显示状态
    if ('setRowNumberDisplay' in this.scrollManager) {
      (this.scrollManager as any).setRowNumberDisplay(this.options.showRowNumber, 50)
    }
    
    this.renderer = new TableRenderer(
      this.canvas,
      this.dataManager,
      this.scrollManager,
      {
        theme: this.options.theme,
        showRowNumber: this.options.showRowNumber,
        showGridLines: this.options.showGridLines
      }
    )
    
    this.eventManager = new EventManager(
      this.canvas,
      this.scrollManager,
      this.dataManager,
      {
        showRowNumber: this.options.showRowNumber
      }
    )
    
    // 设置渲染器引用
    this.eventManager.setRenderer(this.renderer)
    
    // 设置表格实例引用
    this.eventManager.setTable(this)
    
    // 设置分页信息（如果有）
    if (options?.pagination && 'setPageInfo' in this.renderer) {
      this.renderer.setPageInfo(options.pagination.currentPage, options.pagination.pageSize)
    }
    
    // 初始化事件监听
    this.initializeEventHandlers()
    
    // 监听容器尺寸变化
    this.observeResize()
  }

  // 创建画布
  private createCanvas(): HTMLCanvasElement {
    const canvas = document.createElement('canvas')
    canvas.style.width = '100%'
    canvas.style.height = '100%'
    canvas.style.display = 'block'
    
    // 添加ARIA属性
    canvas.setAttribute('role', 'grid')
    canvas.setAttribute('aria-label', 'Data table')
    canvas.setAttribute('tabindex', '0')
    
    this.container.appendChild(canvas)
    
    // 设置初始尺寸
    const rect = this.container.getBoundingClientRect()
    canvas.width = rect.width
    canvas.height = rect.height
    
    return canvas
  }

  // 初始化事件处理
  private initializeEventHandlers(): void {
    // 监听渲染请求
    this.eventManager.on('render' as EventType, () => {
      this.render()
    })
    
    // 监听选择变化
    this.eventManager.on(EventType.SelectionChange, (event: SelectionChangeEvent) => {
      const selection = this.eventManager.getSelection()
      
      // 更新渲染器的选择状态
      if (event.selectedCells) {
        this.renderer.setSelectedCells(event.selectedCells)
      }
      
      // 处理范围选择，null表示清除范围选择
      if (event.selectedRange !== undefined) {
        this.renderer.setSelectionRange(event.selectedRange || null)
      }
      
      // 更新行选择
      if (event.selectedRows !== undefined) {
        this.renderer.setSelectedRows(event.selectedRows)
      }
      
      // 更新列选择
      if (event.selectedColumns !== undefined) {
        this.renderer.setSelectedColumns(event.selectedColumns)
      }
      
      // 更新选择模式
      if (event.selectionMode !== undefined) {
        this.renderer.setSelectionMode(event.selectionMode)
      }
      
      // 更新当前单元格
      this.renderer.setCurrentCell(selection.currentCell)
      
      this.render()
    })
    
    // 监听单元格修改
    this.eventManager.on(EventType.CellChange, (event: CellChangeEvent) => {
      // 数据已经在 DataManager 中更新，只需要重新渲染
      this.render()
    })
    
    // 监听列宽调整
    this.eventManager.on(EventType.ColumnResize, (event) => {
      this.emit(EventType.ColumnResize, event)
    })
    
    // 监听行高调整
    this.eventManager.on('row-resize' as EventType, (event) => {
      this.emit('row-resize' as EventType, event)
    })
    
    // 监听右键菜单
    this.eventManager.on(EventType.ContextMenu, (event: any) => {
      this.showContextMenu(event)
    })
    
    // 监听复制事件
    this.eventManager.on(EventType.Copy, async () => {
      await this.handleCopy()
    })
    
    // 监听粘贴事件
    this.eventManager.on(EventType.Paste, async () => {
      await this.handlePaste()
    })
    
    // 监听剪切事件
    this.eventManager.on(EventType.Cut, async () => {
      await this.handleCut()
    })
    
    // 监听悬停状态变化
    this.eventManager.on('hover-change' as EventType, (event: any) => {
      if (this.renderer.setHoverState) {
        this.renderer.setHoverState({
          hoveredCell: event.hoveredCell,
          hoveredRow: event.hoveredRow,
          hoveredColumn: event.hoveredColumn
        })
      }
    })
    
    // 监听填充柄完成事件
    this.eventManager.on('fill-handle-complete' as EventType, (event: any) => {
      if (event.range && event.direction) {
        // 执行填充操作
        const cells: CellPosition[] = []
        for (let row = event.range.start.row; row <= event.range.end.row; row++) {
          for (let col = event.range.start.col; col <= event.range.end.col; col++) {
            cells.push({ row, col })
          }
        }
        
        // 根据方向获取源单元格值
        let sourceRow = event.range.start.row
        let sourceCol = event.range.start.col
        
        if (event.direction === 'up') {
          sourceRow = event.range.end.row
        } else if (event.direction === 'left') {
          sourceCol = event.range.end.col
        }
        
        const sourceValue = this.getCellValue(sourceRow, sourceCol)
        
        // 填充目标单元格
        cells.forEach(cell => {
          if (cell.row !== sourceRow || cell.col !== sourceCol) {
            this.setCellValue(cell.row, cell.col, sourceValue)
          }
        })
      }
    })
    
    // 监听数据变化事件
    this.eventManager.on('data-change' as EventType, () => {
      this.render()
    })
    
    // 监听列排序事件
    this.eventManager.on('column-sort' as EventType, (event: any) => {
      if (event.column) {
        this.sortByColumn(event.column)
      }
    })
  }

  // 监听容器尺寸变化
  private observeResize(): void {
    if (typeof ResizeObserver === 'undefined') return
    
    // 如果已有观察器，先清理
    if (this.resizeObserver) {
      this.resizeObserver.disconnect()
    }
    
    this.resizeObserver = new ResizeObserver(entries => {
      if (this._isDestroyed) return
      
      for (const entry of entries) {
        const { width, height } = entry.contentRect
        this.resize(width, height)
      }
    })
    
    this.resizeObserver.observe(this.container)
  }

  // 渲染
  private render(): void {
    if (this._isDestroyed) return
    this.renderer.render()
    this.updateAriaAttributes()
  }

  // TableAPI 实现

  // 设置数据
  setData(data: RowData[]): void {
    // 保存旧的列数以检查是否发生变化
    const oldColumnCount = this.dataManager.getColumnCount()
    
    this.dataManager.setData(data)
    this.scrollManager.setDataInfo(data.length, this.columns)
    
    // 验证当前单元格位置
    if (this.eventManager && 'validateCurrentCell' in this.eventManager) {
      (this.eventManager as any).validateCurrentCell()
    }
    
    // 如果列数发生变化，处理列变化
    const newColumnCount = this.dataManager.getColumnCount()
    if (oldColumnCount !== newColumnCount && this.eventManager && 'handleColumnsChange' in this.eventManager) {
      (this.eventManager as any).handleColumnsChange()
    }
    
    // 恢复排序显示（只更新渲染器，不改变数据）
    if (this.renderer && this.currentSortConfig.column) {
      this.renderer.setSortConfig(this.currentSortConfig.column, this.currentSortConfig.direction)
    }
    
    this.render()
  }

  // 设置列配置
  setColumns(columns: Column[]): void {
    this.columns = columns
    
    // 更新DataManager的列配置
    if ('setColumns' in this.dataManager) {
      (this.dataManager as any).setColumns(columns)
    }
    
    // 更新滚动管理器
    this.scrollManager.setDataInfo(this.dataManager.getRowCount(), columns)
    
    // 通知EventManager列发生变化
    if (this.eventManager && 'handleColumnsChange' in this.eventManager) {
      (this.eventManager as any).handleColumnsChange()
    }
    
    this.render()
  }

  // 获取数据
  getData(): RowData[] {
    return this.dataManager.getData()
  }

  // 获取单元格值
  getCellValue(row: number, col: number): CellValue {
    const column = this.columns[col]
    return this.dataManager.getCellValue(row, column.field)
  }

  // 设置单元格值
  setCellValue(row: number, col: number, value: CellValue): void {
    const column = this.columns[col]
    if (this.dataManager.setCellValue(row, column.field, value)) {
      this.render()
    }
  }

  // 选择单元格
  selectCell(row: number, col: number): void {
    this.eventManager['selectedCell'] = { row, col }
    this.eventManager['currentCell'] = { row, col }
    this.eventManager['selectionRange'] = null
    this.eventManager['selectedCells'].clear()
    
    this.renderer.setSelectedCells([{ row, col }])
    this.renderer.setSelectionRange(null)
    this.renderer.setCurrentCell({ row, col })
    
    // 触发选择变化事件
    this.emit(EventType.SelectionChange, {
      selectedCells: [{ row, col }],
      selectedRange: undefined
    })
    
    this.render()
  }

  // 选择范围
  selectRange(range: CellRange): void {
    this.eventManager['selectionRange'] = range
    this.eventManager['selectedCells'].clear()
    this.renderer.setSelectionRange(range)
    
    // 计算选中的单元格
    const cells: CellPosition[] = []
    const minRow = Math.min(range.start.row, range.end.row)
    const maxRow = Math.max(range.start.row, range.end.row)
    const minCol = Math.min(range.start.col, range.end.col)
    const maxCol = Math.max(range.start.col, range.end.col)
    
    for (let row = minRow; row <= maxRow; row++) {
      for (let col = minCol; col <= maxCol; col++) {
        cells.push({ row, col })
      }
    }
    
    this.renderer.setSelectedCells(cells)
    this.render()
  }

  // 清除选择
  clearSelection(): void {
    this.eventManager['selectedCell'] = null
    this.eventManager['selectionRange'] = null
    this.eventManager['selectedCells'].clear()
    
    this.renderer.setSelectedCells([])
    this.renderer.setSelectionRange(null)
    this.renderer.setCurrentCell(null)
    this.render()
  }

  // 选择行
  selectRow(row: number, extend: boolean = false): void {
    this.eventManager.selectRow(row, extend)
  }
  
  // 选择多行
  selectRows(rows: number[]): void {
    this.eventManager.clearAllSelection()
    rows.forEach(row => this.eventManager.selectRow(row, true))
  }
  
  // 选择列
  selectColumn(col: number, extend: boolean = false): void {
    this.eventManager.selectColumn(col, extend)
  }
  
  // 选择多列
  selectColumns(columns: number[]): void {
    this.eventManager.clearAllSelection()
    columns.forEach(col => this.eventManager.selectColumn(col, true))
  }
  
  // 获取选中的行
  getSelectedRows(): number[] {
    const selection = this.eventManager.getSelection()
    return selection.selectedRows
  }
  
  // 获取选中的列
  getSelectedColumns(): number[] {
    const selection = this.eventManager.getSelection()
    return selection.selectedColumns
  }
  
  // 获取选择模式
  getSelectionMode(): SelectionMode {
    const selection = this.eventManager.getSelection()
    return selection.selectionMode
  }

  // 获取选中的单元格
  getSelectedCells(): CellPosition[] {
    const selection = this.eventManager.getSelection()
    const cells: CellPosition[] = []
    
    // 多选模式
    if (this.eventManager['selectedCells'] && this.eventManager['selectedCells'].size > 0) {
      this.eventManager['selectedCells'].forEach((key: string) => {
        const [row, col] = key.split(',').map(Number)
        cells.push({ row, col })
      })
    }
    // 范围选择模式
    else if (selection.selectionRange) {
      const minRow = Math.min(selection.selectionRange.start.row, selection.selectionRange.end.row)
      const maxRow = Math.max(selection.selectionRange.start.row, selection.selectionRange.end.row)
      const minCol = Math.min(selection.selectionRange.start.col, selection.selectionRange.end.col)
      const maxCol = Math.max(selection.selectionRange.start.col, selection.selectionRange.end.col)
      
      for (let row = minRow; row <= maxRow; row++) {
        for (let col = minCol; col <= maxCol; col++) {
          cells.push({ row, col })
        }
      }
    }
    // 单选模式
    else if (selection.selectedCell) {
      cells.push(selection.selectedCell)
    }
    
    return cells
  }

  // 开始编辑
  startEdit(row: number, col: number, initialValue?: string): void {
    const column = this.columns[col]
    if (!column.editable) return
    
    // 如果已经在编辑，先结束当前编辑
    if (this.isEditing()) {
      this.endEdit(true)
    }
    
    // 确保单元格完全可见
    this.ensureCellVisible(row, col)
    
    // 等待滚动动画完成
    setTimeout(() => {
      this.eventManager['isEditing'] = true
      this.eventManager['editingCell'] = { row, col }
      this.editingCell = { row, col }
      this.renderer.setEditingCell({ row, col })
      
      // 创建编辑器
      this.createEditor(row, col, initialValue)
      
      // 触发编辑开始事件
      this.emit(EventType.EditStart, {
        row,
        col,
        field: column.field,
        value: this.getCellValue(row, col)
      })
    }, 100) // 给滚动动画更多时间
  }

  // 创建编辑器
  private createEditor(row: number, col: number, initialValue?: string): void {
    const column = this.columns[col]
    const cellBounds = this.getCellBounds(row, col)
    if (!cellBounds) return
    
    // 创建编辑器容器
    this.editor = document.createElement('div')
    this.editor.className = 'canvas-table-editor'
    this.editor.style.cssText = `
      position: fixed;
      left: ${cellBounds.x}px;
      top: ${cellBounds.y}px;
      width: ${cellBounds.width}px;
      height: ${cellBounds.height}px;
      z-index: 1000;
      box-sizing: border-box;
      overflow: hidden;
    `
    
    // 使用编辑器工厂创建编辑器
    this.currentEditor = editorFactory.createEditor(column)
    if (!this.currentEditor) {
      console.error('Failed to create editor for column:', column)
      // 如果创建失败，使用默认的文本编辑器
      const input = document.createElement('input')
      input.type = 'text'
      input.style.width = '100%'
      input.style.height = '100%'
      input.style.border = '2px solid #3b82f6'
      input.style.outline = 'none'
      input.style.padding = '0 8px'
      input.style.fontSize = '13px'
      input.style.fontFamily = 'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif'
      input.style.boxSizing = 'border-box'
      input.style.background = 'white'
      input.style.borderRadius = '4px'
      input.style.position = 'absolute'
      input.style.top = '0'
      input.style.left = '0'
      input.value = String(this.getCellValue(row, col) || '')
      
      // 处理输入事件
      input.addEventListener('keydown', (e) => {
        if (e.key === 'Enter' || e.key === 'Tab') {
          e.preventDefault()
          this.endEdit(true)
          if (e.key === 'Tab') {
            const nextCol = e.shiftKey ? col - 1 : col + 1
            if (nextCol >= 0 && nextCol < this.columns.length) {
              this.selectCell(row, nextCol)
              this.startEdit(row, nextCol)
            }
          }
        } else if (e.key === 'Escape') {
          e.preventDefault()
          this.endEdit(false)
        }
      })
      
      input.addEventListener('blur', () => {
        this.endEdit(true)
      })
      
      this.editor.appendChild(input)
      this.canvas.parentElement?.appendChild(this.editor)
      
      // 聚焦并全选
      input.focus()
      input.select()
      return
    }
    
    // 设置值变化回调
    this.currentEditor.onValueChange = (value: CellValue) => {
      // 可以在这里实现实时验证或预览
    }
    
    // 创建编辑器
    const currentValue = this.getCellValue(row, col)
    this.currentEditor.create(this.editor, currentValue, column)
    
    // 添加键盘事件处理
    this.editor.addEventListener('keydown', ((e: Event) => {
      const keyEvent = e as KeyboardEvent
      
      // Enter 键处理
      if (keyEvent.key === 'Enter') {
        // 对于多行文本编辑器，需要 Ctrl/Cmd + Enter 才能结束编辑
        if (column.editType === 'textarea' && !(keyEvent.ctrlKey || keyEvent.metaKey)) {
          return // 允许换行
        }
        keyEvent.preventDefault()
        this.endEdit(true)
      } 
      // Escape 键取消编辑
      else if (keyEvent.key === 'Escape') {
        keyEvent.preventDefault()
        this.endEdit(false)
      } 
      // Tab 键移动到下一个单元格
      else if (keyEvent.key === 'Tab') {
        keyEvent.preventDefault()
        this.endEdit(true)
        // 移动到下一个单元格
        const nextCol = keyEvent.shiftKey ? col - 1 : col + 1
        if (nextCol >= 0 && nextCol < this.columns.length) {
          this.selectCell(row, nextCol)
          this.startEdit(row, nextCol)
        }
      }
    }) as EventListener)
    
    // 添加失焦事件处理
    this.editor.addEventListener('focusout', (e) => {
      // 延迟处理，避免与其他事件冲突
      setTimeout(() => {
        // 检查焦点是否还在编辑器内
        if (this.editor && !this.editor.contains(document.activeElement)) {
          this.endEdit(true)
        }
      }, 100)
    })
    
    // 添加到 document.body 以避免影响表格布局
    document.body.appendChild(this.editor)
    
    // 聚焦编辑器
    this.currentEditor.focus()
  }

  // 获取单元格边界
  private getCellBounds(row: number, col: number): { x: number; y: number; width: number; height: number } | null {
    const viewport = this.scrollManager.getViewport()
    
    // 检查单元格是否在可见范围内
    if (row < viewport.startRow || row > viewport.endRow) return null
    if (col < viewport.startCol || col > viewport.endCol) return null
    
    const column = this.columns[col]
    const x = this.scrollManager.getColumnX(col) + (this.options.showRowNumber ? this.renderer['rowNumberWidth'] : 0)
    const y = this.scrollManager.getRowY(row)
    const width = column.width || 100
    const height = this.options.rowHeight
    
    // 获取画布相对于视口的位置
    const canvasRect = this.canvas.getBoundingClientRect()
    
    // 获取滚动条信息
    const scrollbarInfo = this.scrollManager.getScrollbarInfo()
    const scrollbarWidth = this.scrollManager.getScrollbarWidth()
    
    // 计算实际的单元格位置
    let cellX = canvasRect.left + x
    let cellY = canvasRect.top + y
    let cellWidth = width
    let cellHeight = height
    
    // 如果单元格会覆盖垂直滚动条，调整宽度
    if (scrollbarInfo.vertical.visible && 
        cellX + cellWidth > canvasRect.right - scrollbarWidth) {
      cellWidth = Math.max(10, canvasRect.right - scrollbarWidth - cellX)
    }
    
    // 如果单元格会覆盖水平滚动条，调整高度
    if (scrollbarInfo.horizontal.visible && 
        cellY + cellHeight > canvasRect.bottom - scrollbarWidth) {
      cellHeight = Math.max(10, canvasRect.bottom - scrollbarWidth - cellY)
    }
    
    // 确保编辑器不会超出画布边界
    cellWidth = Math.max(10, Math.min(cellWidth, canvasRect.right - cellX))
    cellHeight = Math.max(10, Math.min(cellHeight, canvasRect.bottom - cellY))
    
    return {
      x: cellX,
      y: cellY,
      width: cellWidth,
      height: cellHeight
    }
  }

  // 结束编辑
  endEdit(save?: boolean): void {
    if (!this.eventManager['isEditing'] || !this.editingCell || !this.editor || !this.currentEditor) return
    
    const editingRow = this.editingCell.row
    const editingCol = this.editingCell.col
    const column = this.columns[editingCol]
    const oldValue = this.getCellValue(editingRow, editingCol)
    
    if (save) {
      // 验证值
      const validationResult = this.currentEditor.validate()
      if (!validationResult.valid) {
        this.showValidationError(validationResult.message || '验证失败')
            return
        }
      
      // 获取新值
      const newValue = this.currentEditor.getValue()
        
        // 设置新值
        if (newValue !== oldValue) {
          this.setCellValue(editingRow, editingCol, newValue)
        }
      }
    
    // 销毁编辑器
    if (this.currentEditor) {
      this.currentEditor.destroy()
      this.currentEditor = null
    }
    
    // 清理编辑器容器
    if (this.editor) {
      this.editor.remove()
      this.editor = null
    }
    
    this.eventManager['isEditing'] = false
    this.eventManager['editingCell'] = null
    this.editingCell = null
    this.renderer.setEditingCell(null)
    
    // 重新聚焦画布
    this.canvas.focus()
    
    // 触发编辑结束事件
    this.emit(EventType.EditEnd, {
      row: editingRow,
      col: editingCol,
      field: column.field,
      saved: save
    })
    
    this.render()
  }

  // 显示验证错误
  private showValidationError(message: string): void {
    // 创建或更新错误提示元素
    let errorTooltip = document.getElementById('canvas-table-error-tooltip')
    if (!errorTooltip) {
      errorTooltip = document.createElement('div')
      errorTooltip.id = 'canvas-table-error-tooltip'
      errorTooltip.style.cssText = `
        position: fixed;
        padding: 8px 12px;
        background-color: #ef4444;
        color: white;
        font-size: 14px;
        border-radius: 6px;
        box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        z-index: 10000;
        pointer-events: none;
        opacity: 0;
        transition: opacity 0.2s ease-in-out;
        max-width: 300px;
        white-space: pre-wrap;
        word-wrap: break-word;
      `
      document.body.appendChild(errorTooltip)
    }
    
    // 设置内容和位置
    errorTooltip.textContent = message
    
    // 获取当前编辑单元格的位置
    if (this.editingCell && this.editor) {
      const rect = this.editor.getBoundingClientRect()
      const tooltipRect = errorTooltip.getBoundingClientRect()
      
      // 计算位置（优先显示在下方）
      let top = rect.bottom + 5
      let left = rect.left
      
      // 如果下方空间不够，显示在上方
      if (top + tooltipRect.height > window.innerHeight) {
        top = rect.top - tooltipRect.height - 5
      }
      
      // 确保不超出右边界
      if (left + tooltipRect.width > window.innerWidth) {
        left = window.innerWidth - tooltipRect.width - 10
      }
      
      errorTooltip.style.left = `${left}px`
      errorTooltip.style.top = `${top}px`
    }
    
    // 显示错误提示
    errorTooltip.style.opacity = '1'
    
    // 3秒后自动隐藏
    setTimeout(() => {
      if (errorTooltip) {
        errorTooltip.style.opacity = '0'
        setTimeout(() => {
          errorTooltip.remove()
        }, 200)
      }
    }, 3000)
  }

  // 是否正在编辑
  isEditing(): boolean {
    return this.eventManager['isEditing'] || false
  }

  // 撤销
  undo(): void {
    if (this.dataManager.undo()) {
      this.render()
    }
  }

  // 重做
  redo(): void {
    if (this.dataManager.redo()) {
      this.render()
    }
  }

  // 是否可以撤销
  canUndo(): boolean {
    return this.dataManager.canUndo()
  }

  // 是否可以重做
  canRedo(): boolean {
    return this.dataManager.canRedo()
  }

  // 刷新表格
  refresh(): void {
    if (this._isDestroyed) return
    
    // 直接渲染，不使用批处理
    this.renderer.render()
    this.updateAriaAttributes()
  }

  // 调整大小
  resize(width?: number, height?: number): void {
    const rect = this.container.getBoundingClientRect()
    const newWidth = width ?? rect.width
    const newHeight = height ?? rect.height
    
    // 更新画布尺寸
    this.canvas.width = newWidth
    this.canvas.height = newHeight
    this.canvas.style.width = newWidth + 'px'
    this.canvas.style.height = newHeight + 'px'
    
    // 更新滚动管理器
    this.scrollManager.setContainerSize(newWidth, newHeight)
    
    // 重新设置高DPI
    const dpr = window.devicePixelRatio || 1
    this.canvas.width = newWidth * dpr
    this.canvas.height = newHeight * dpr
    const ctx = this.canvas.getContext('2d')
    if (ctx) {
      ctx.scale(dpr, dpr)
    }
    
    this.render()
  }

  // 添加事件监听
  on(event: EventType, handler: EventHandler): void {
    if (!this.eventHandlers.has(event)) {
      this.eventHandlers.set(event, new Set())
    }
    this.eventHandlers.get(event)!.add(handler)
    this.eventManager.on(event, handler)
  }

  // 移除事件监听
  off(event: EventType, handler: EventHandler): void {
    const handlers = this.eventHandlers.get(event)
    if (handlers) {
      handlers.delete(handler)
    }
    this.eventManager.off(event, handler)
  }

  // 销毁
  destroy(): void {
    if (this._isDestroyed) return
    
    this._isDestroyed = true
    
    // 先清理所有事件监听器
    this.eventHandlers.clear()
    
    // 销毁各个模块
    if (this.eventManager) {
      this.eventManager.destroy()
    }
    
    // 销毁右键菜单
    if (this.contextMenu) {
      this.contextMenu.destroy()
      this.contextMenu = null
    }
    
    // 清理编辑器
    if (this.editor && this.editor.parentNode) {
      this.editor.parentNode.removeChild(this.editor)
      this.editor = null
    }
    
    // 移除画布 - 使用 try-catch 防止 DOM 已被移除的情况
    try {
      if (this.canvas && this.canvas.parentNode) {
        this.canvas.parentNode.removeChild(this.canvas)
      }
    } catch (error) {
      console.warn('Canvas already removed from DOM:', error)
    }
    
    // 清理 ResizeObserver
    if (this.resizeObserver) {
      this.resizeObserver.disconnect()
      this.resizeObserver = null
    }
  }

  // 检查是否已销毁
  isDestroyed(): boolean {
    return this._isDestroyed
  }

  // 扩展方法

  // 插入行
  insertRow(index: number, row?: RowData): void {
    this.dataManager.insertRow(index, row)
    this.scrollManager.setDataInfo(this.dataManager.getRowCount(), this.columns)
    
    // 验证当前单元格位置
    if (this.eventManager && 'validateCurrentCell' in this.eventManager) {
      (this.eventManager as any).validateCurrentCell()
    }
    
    this.render()
  }

  // 删除行
  deleteRow(index: number): void {
    if (this.dataManager.deleteRow(index)) {
      this.scrollManager.setDataInfo(this.dataManager.getRowCount(), this.columns)
      
      // 验证当前单元格位置
      if (this.eventManager && 'validateCurrentCell' in this.eventManager) {
        (this.eventManager as any).validateCurrentCell()
      }
      
      this.render()
    }
  }

  // 批量删除行
  deleteRows(indices: number[]): void {
    if (indices.length === 0) return
    
    // 从大到小排序，避免删除时索引变化影响
    const sortedIndices = [...indices].sort((a, b) => b - a)
    
    // 使用批量模式
    this.dataManager.beginBatch()
    
    try {
      sortedIndices.forEach(index => {
        this.dataManager.deleteRow(index)
      })
      
      this.dataManager.endBatch()
      
      // 更新滚动管理器
      this.scrollManager.setDataInfo(this.dataManager.getRowCount(), this.columns)
      
      // 验证当前单元格位置
      if (this.eventManager && 'validateCurrentCell' in this.eventManager) {
        (this.eventManager as any).validateCurrentCell()
      }
      
      // 触发批量删除事件
      this.emit(EventType.BatchDelete, {
        operation: 'delete',
        rows: indices
      })
      
      this.render()
    } catch (error) {
      this.dataManager.cancelBatch()
      throw error
    }
  }

  // 获取修改的数据
  getChanges(): {
    modified: Array<{ row: number; field: string; value: CellValue; oldValue: CellValue; newValue: CellValue }>
    inserted: Array<{ index: number; data: RowData }>
    deleted: Array<{ index: number; data: RowData }>
  } {
    const modified: Array<{ row: number; field: string; value: CellValue; oldValue: CellValue; newValue: CellValue }> = []
    const inserted: Array<{ index: number; data: RowData }> = []
    const deleted: Array<{ index: number; data: RowData }> = []
    
    // 使用 DataManager 的改进版 getChanges 方法获取完整的修改记录
    const changes = this.dataManager.getChanges()
    changes.forEach(change => {
      modified.push({
        row: change.row,
        field: change.field,
        value: change.newValue,  // 保持向后兼容
        oldValue: change.oldValue,
        newValue: change.newValue
      })
    })
    
    // 获取插入的行
    this.dataManager.getInsertedRows().forEach(index => {
      inserted.push({
        index,
        data: this.dataManager.getData()[index]
      })
    })
    
    // 获取删除的行
    this.dataManager.getDeletedRows().forEach((data, index) => {
      deleted.push({ index, data })
    })
    
    return { modified, inserted, deleted }
  }

  // 提交修改
  commit(): void {
    this.dataManager.commit()
    this.render()
  }

  // 回滚修改
  rollback(): void {
    this.dataManager.rollback()
    this.scrollManager.setDataInfo(this.dataManager.getRowCount(), this.columns)
    this.render()
  }

  // 滚动到指定单元格
  scrollToCell(row: number, col: number): void {
    this.scrollManager.scrollToCell(row, col)
    this.render()
  }

  // 设置主题
  setTheme(theme: Partial<TableOptions['theme']>): void {
    this.renderer.updateTheme(theme || {})
    this.render()
  }

  // 切换行号显示
  toggleRowNumbers(show: boolean): void {
    this.options.showRowNumber = show
    this.renderer.toggleRowNumbers(show)
    
    // 更新滚动管理器的行号显示状态
    if ('setRowNumberDisplay' in this.scrollManager) {
      (this.scrollManager as any).setRowNumberDisplay(show, 50)
    }
    
    this.render()
  }

  // 切换网格线显示
  toggleGridLines(show: boolean): void {
    this.options.showGridLines = show
    this.renderer.toggleGridLines(show)
    this.render()
  }

  // 显示右键菜单
  private showContextMenu(event: any): void {
    if (!this.contextMenu) {
      this.contextMenu = new ContextMenu()
    }
    
    // 检查是否是列头右键菜单
    if (event.type === 'column-header') {
      const menuItems = ContextMenu.createColumnHeaderContextMenu({
        column: event.column,
        columnIndex: event.col,
        currentSortColumn: this.currentSortConfig.column,
        currentSortDirection: this.currentSortConfig.direction,
        onSortAsc: () => {
          this.sortByColumn(event.column.field, 'asc')
        },
        onSortDesc: () => {
          this.sortByColumn(event.column.field, 'desc')
        },
        onClearSort: () => {
          this.clearSort()
        }
        // 这里可以添加更多列操作，如插入列、删除列等
      })
      
      this.contextMenu.setItems(menuItems)
      this.contextMenu.show(event.x, event.y)
      return
    }
    
    // 处理普通单元格右键菜单
    const selection = this.eventManager.getSelection()
    
    const menuItems = ContextMenu.createTableContextMenu({
      selectedCells: event.selectedCells || this.getSelectedCells(),
      selectedRows: selection.selectedRows,
      selectedColumns: selection.selectedColumns,
      hasChanges: this.dataManager.getModifiedCells().size > 0 || 
                  this.dataManager.getInsertedRows().size > 0 || 
                  this.dataManager.getDeletedRows().size > 0,
      canUndo: this.canUndo(),
      canRedo: this.canRedo(),
      onCopy: () => this.eventManager['copy'](),
      onPaste: () => this.eventManager['paste'](),
      onCut: () => this.eventManager['cut'](),
      onDelete: () => this.eventManager['deleteSelectedCells'](),
      onInsertRow: () => {
        const selection = this.eventManager.getSelection()
        const row = selection.currentCell ? selection.currentCell.row + 1 : this.dataManager.getRowCount()
        this.insertRow(row)
      },
      onDeleteRow: () => {
        this.batchDeleteRows()
      },
      onSelectRow: event.row !== undefined ? () => {
        this.selectRow(event.row)
      } : undefined,
      onSelectColumn: event.col !== undefined ? () => {
        this.selectColumn(event.col)
      } : undefined,
      onSelectAll: () => {
        this.selectRange({
          start: { row: 0, col: 0 },
          end: { row: this.dataManager.getRowCount() - 1, col: this.columns.length - 1 }
        })
      },
      onBatchEdit: () => {
        // 触发批量编辑事件，让外部组件处理
        this.emit(EventType.BatchEdit, {
          operation: 'edit',
          cells: this.getSelectedCells()
        })
      },
      onBatchClear: () => {
        if (confirm('确定要清空选中的单元格吗？')) {
          this.batchClearSelected()
        }
      },
      onBatchFill: (direction: string) => {
        this.batchFill(direction as 'down' | 'up' | 'right' | 'left')
      },
      onUndo: () => this.undo(),
      onRedo: () => this.redo()
    })
    
    this.contextMenu.setItems(menuItems)
    this.contextMenu.show(event.x, event.y)
  }
  
  // 处理复制
  private async handleCopy(): Promise<void> {
    // 复制操作已在 EventManager 中处理
  }
  
  // 处理粘贴
  private async handlePaste(): Promise<void> {
    // 粘贴操作已在 EventManager 中处理
  }
  
  // 处理剪切
  private async handleCut(): Promise<void> {
    // 剪切操作已在 EventManager 中处理
  }

  // 批量更新单元格
  batchUpdate(updates: Array<{ row: number; col: number; value: CellValue }>): void {
    const cellUpdates = updates.map(update => ({
      row: update.row,
      field: this.columns[update.col].field,
      value: update.value
    }))
    
    if (this.dataManager.batchSetCellValues(cellUpdates)) {
      this.render()
    }
  }

  // 批量编辑选中的单元格
  batchEditSelected(value: CellValue | ((oldValue: CellValue) => CellValue)): void {
    const cells = this.getSelectedCells()
    if (cells.length === 0) return
    
    const updates: Array<{ row: number; col: number; value: CellValue }> = []
    
    cells.forEach(cell => {
      const column = this.columns[cell.col]
      if (!column.editable) return
      
      const oldValue = this.getCellValue(cell.row, cell.col)
      const newValue = typeof value === 'function' ? value(oldValue) : value
      
      // 验证新值
      if (column.validator) {
        const result = column.validator(newValue)
        if (!result.valid) {
          console.warn(`验证失败 [${cell.row},${cell.col}]: ${result.message}`)
          return
        }
      }
      
      updates.push({ row: cell.row, col: cell.col, value: newValue })
    })
    
    if (updates.length > 0) {
      this.batchUpdate(updates)
      
      // 触发批量编辑事件
      this.emit(EventType.BatchEdit, {
        operation: 'edit',
        cells: updates.map(u => ({ row: u.row, col: u.col })),
        value: value
      })
    }
  }
  
  // 批量删除选中的单元格内容
  batchClearSelected(): void {
    this.batchEditSelected(null)
  }
  
  // 批量填充
  batchFill(direction: 'down' | 'up' | 'right' | 'left'): void {
    const cells = this.getSelectedCells()
    if (cells.length < 2) return
    
    // 找到选中区域的边界
    const minRow = Math.min(...cells.map(c => c.row))
    const maxRow = Math.max(...cells.map(c => c.row))
    const minCol = Math.min(...cells.map(c => c.col))
    const maxCol = Math.max(...cells.map(c => c.col))
    
    const updates: Array<{ row: number; col: number; value: CellValue }> = []
    
    switch (direction) {
      case 'down':
        // 使用第一行的值填充下面的行
        for (let col = minCol; col <= maxCol; col++) {
          const sourceValue = this.getCellValue(minRow, col)
          for (let row = minRow + 1; row <= maxRow; row++) {
            if (this.columns[col].editable) {
              updates.push({ row, col, value: sourceValue })
            }
          }
        }
        break
        
      case 'up':
        // 使用最后一行的值填充上面的行
        for (let col = minCol; col <= maxCol; col++) {
          const sourceValue = this.getCellValue(maxRow, col)
          for (let row = minRow; row < maxRow; row++) {
            if (this.columns[col].editable) {
              updates.push({ row, col, value: sourceValue })
            }
          }
        }
        break
        
      case 'right':
        // 使用第一列的值填充右边的列
        for (let row = minRow; row <= maxRow; row++) {
          const sourceValue = this.getCellValue(row, minCol)
          for (let col = minCol + 1; col <= maxCol; col++) {
            if (this.columns[col].editable) {
              updates.push({ row, col, value: sourceValue })
            }
          }
        }
        break
        
      case 'left':
        // 使用最后一列的值填充左边的列
        for (let row = minRow; row <= maxRow; row++) {
          const sourceValue = this.getCellValue(row, maxCol)
          for (let col = minCol; col < maxCol; col++) {
            if (this.columns[col].editable) {
              updates.push({ row, col, value: sourceValue })
            }
          }
        }
        break
    }
    
    if (updates.length > 0) {
      this.batchUpdate(updates)
      
      // 触发批量操作事件
      this.emit(EventType.BatchOperation, {
        operation: 'fill',
        cells: updates.map(u => ({ row: u.row, col: u.col })),
        options: { direction }
      })
    }
  }
  
  // 批量删除选中的行
  batchDeleteRows(): void {
    const selection = this.eventManager.getSelection()
    const rowsToDelete = new Set<number>()
    
    // 如果有选中的行，删除这些行
    if (selection.selectedRows && selection.selectedRows.length > 0) {
      selection.selectedRows.forEach(row => rowsToDelete.add(row))
    } 
    // 否则基于选中的单元格获取要删除的行
    else {
      const cells = this.getSelectedCells()
      if (cells.length === 0) return
      
      cells.forEach(cell => rowsToDelete.add(cell.row))
    }
    
    if (rowsToDelete.size === 0) return
    
    // 批量删除
    this.deleteRows(Array.from(rowsToDelete))
  }
  
  // 获取选中区域的统计信息
  getSelectionStats(): {
    count: number
    sum: number | null
    average: number | null
    min: number | null
    max: number | null
    uniqueCount: number
  } {
    const cells = this.getSelectedCells()
    if (cells.length === 0) {
      return { count: 0, sum: null, average: null, min: null, max: null, uniqueCount: 0 }
    }
    
    const values: number[] = []
    const uniqueValues = new Set<any>()
    let count = 0
    
    cells.forEach(cell => {
      const value = this.getCellValue(cell.row, cell.col)
      if (value !== null && value !== undefined) {
        count++
        uniqueValues.add(value)
        
        if (typeof value === 'number') {
          values.push(value)
        }
      }
    })
    
    if (values.length === 0) {
      return { count, sum: null, average: null, min: null, max: null, uniqueCount: uniqueValues.size }
    }
    
    const sum = values.reduce((a, b) => a + b, 0)
    const average = sum / values.length
    const min = Math.min(...values)
    const max = Math.max(...values)
    
    return { count, sum, average, min, max, uniqueCount: uniqueValues.size }
  }

  // 查找单元格
  findCell(predicate: (value: CellValue, row: number, col: number) => boolean): CellPosition | null {
    for (let row = 0; row < this.dataManager.getRowCount(); row++) {
      for (let col = 0; col < this.columns.length; col++) {
        const value = this.getCellValue(row, col)
        if (predicate(value, row, col)) {
          return { row, col }
        }
      }
    }
    return null
  }

  // 查找所有匹配的单元格
  findAllCells(predicate: (value: CellValue, row: number, col: number) => boolean): CellPosition[] {
    const cells: CellPosition[] = []
    
    for (let row = 0; row < this.dataManager.getRowCount(); row++) {
      for (let col = 0; col < this.columns.length; col++) {
        const value = this.getCellValue(row, col)
        if (predicate(value, row, col)) {
          cells.push({ row, col })
        }
      }
    }
    
    return cells
  }

  // 高亮单元格
  highlightCells(cells: CellPosition[], className?: string): void {
    // TODO: 实现单元格高亮功能
    this.render()
  }

  // 清除高亮
  clearHighlight(): void {
    // TODO: 清除单元格高亮
    this.render()
  }

  // 导出数据
  exportData(options?: {
    format?: 'json' | 'csv' | 'tsv'
    includeHeaders?: boolean
    selectedOnly?: boolean
  }): string {
    const format = options?.format || 'json'
    const includeHeaders = options?.includeHeaders ?? true
    const selectedOnly = options?.selectedOnly ?? false
    
    let data: RowData[]
    
    if (selectedOnly) {
      const selectedCells = this.getSelectedCells()
      if (selectedCells.length === 0) return ''
      
      // 获取选中区域的数据
      const rows = new Map<number, RowData>()
      selectedCells.forEach(cell => {
        if (!rows.has(cell.row)) {
          rows.set(cell.row, {})
        }
        const column = this.columns[cell.col]
        rows.get(cell.row)![column.field] = this.getCellValue(cell.row, cell.col)
      })
      data = Array.from(rows.values())
    } else {
      data = this.dataManager.getData()
    }
    
    switch (format) {
      case 'csv':
      case 'tsv':
        const delimiter = format === 'csv' ? ',' : '\t'
        const lines: string[] = []
        
        if (includeHeaders) {
          lines.push(this.columns.map(col => `"${col.title}"`).join(delimiter))
        }
        
        data.forEach(row => {
          const values = this.columns.map(col => {
            const value = row[col.field]
            if (value === null || value === undefined) return ''
            const str = String(value)
            // 转义引号并用引号包裹
            return `"${str.replace(/"/g, '""')}"`
          })
          lines.push(values.join(delimiter))
        })
        
        return lines.join('\n')
        
      case 'json':
      default:
        return JSON.stringify(data, null, 2)
    }
  }

  // 导入数据
  importData(data: string, options?: {
    format?: 'json' | 'csv' | 'tsv'
    hasHeaders?: boolean
    append?: boolean
  }): void {
    const format = options?.format || 'json'
    const hasHeaders = options?.hasHeaders ?? true
    const append = options?.append ?? false
    
    let parsedData: RowData[] = []
    
    try {
      switch (format) {
        case 'csv':
        case 'tsv':
          const delimiter = format === 'csv' ? ',' : '\t'
          const lines = data.trim().split('\n')
          
          if (lines.length === 0) return
          
          let startLine = 0
          if (hasHeaders) {
            startLine = 1
            // 可以解析标题行来映射字段
          }
          
          for (let i = startLine; i < lines.length; i++) {
            const values = this.parseCSVLine(lines[i], delimiter)
            const row: RowData = {}
            
            this.columns.forEach((col, index) => {
              if (index < values.length) {
                row[col.field] = this.parseValue(values[index], col.type)
              }
            })
            
            parsedData.push(row)
          }
          break
          
        case 'json':
        default:
          parsedData = JSON.parse(data)
          if (!Array.isArray(parsedData)) {
            throw new Error('数据必须是数组格式')
          }
          break
      }
      
      if (append) {
        const currentData = this.dataManager.getData()
        this.setData([...currentData, ...parsedData])
      } else {
        this.setData(parsedData)
      }
    } catch (error) {
      console.error('导入数据失败:', error)
      throw error
    }
  }

  // 解析CSV行
  private parseCSVLine(line: string, delimiter: string): string[] {
    const values: string[] = []
    let current = ''
    let inQuotes = false
    
    for (let i = 0; i < line.length; i++) {
      const char = line[i]
      const nextChar = line[i + 1]
      
      if (char === '"') {
        if (inQuotes && nextChar === '"') {
          current += '"'
          i++ // 跳过下一个引号
        } else {
          inQuotes = !inQuotes
        }
      } else if (char === delimiter && !inQuotes) {
        values.push(current)
        current = ''
      } else {
        current += char
      }
    }
    
    values.push(current)
    return values
  }

  // 解析值
  private parseValue(value: string, type?: string): any {
    if (value === '') return null
    
    switch (type) {
      case 'number':
        const num = Number(value)
        return isNaN(num) ? value : num
      case 'boolean':
        return value.toLowerCase() === 'true' || value === '1'
      case 'date':
        return new Date(value)
      default:
        return value
    }
  }

  // 获取表格统计信息
  getStatistics(): {
    totalRows: number
    totalColumns: number
    modifiedCells: number
    insertedRows: number
    deletedRows: number
  } {
    return {
      totalRows: this.dataManager.getRowCount(),
      totalColumns: this.columns.length,
      modifiedCells: this.dataManager.getModifiedCells().size,
      insertedRows: this.dataManager.getInsertedRows().size,
      deletedRows: this.dataManager.getDeletedRows().size
    }
  }

  // ===== 排序功能 =====
  
  // 按列排序
  sortByColumn(columnField: string, direction?: 'asc' | 'desc'): void {
    const column = this.columns.find(col => col.field === columnField)
    if (!column || column.sortable === false) return
    
    // 获取当前排序状态以决定下一个状态
    let nextDirection: 'asc' | 'desc' | null = direction || null
    
    // 如果没有指定方向，按照 null -> asc -> desc -> null 的顺序切换
    if (!direction) {
      if (this.currentSortConfig.column === columnField) {
        if (this.currentSortConfig.direction === 'asc') {
          nextDirection = 'desc'
        } else if (this.currentSortConfig.direction === 'desc') {
          nextDirection = null
        } else {
          nextDirection = 'asc'
        }
      } else {
        nextDirection = 'asc'
      }
    }
    
    // 保存排序配置到实例属性
    this.currentSortConfig = {
      column: nextDirection ? columnField : null,
      direction: nextDirection
    }
    
    // 更新渲染器的排序配置
    if (this.renderer) {
      this.renderer.setSortConfig(
        this.currentSortConfig.column,
        this.currentSortConfig.direction
      )
    }
    
    // 检查排序模式
    const sortMode = this.options.sortMode || 'local'
    
    if (sortMode === 'local' && nextDirection) {
      // 本地排序模式：使用 DataManager 进行排序
      const compareFn = column.compareFn
      this.dataManager.sortByColumn(columnField, nextDirection, compareFn)
    } else if (sortMode === 'local' && !nextDirection) {
      // 恢复原始顺序
      this.dataManager.restoreOriginalOrder()
    }
    
    // 无论是本地还是远程模式，都触发排序事件
    this.emit(EventType.Sort, {
      column: this.currentSortConfig.column,
      direction: this.currentSortConfig.direction,
      columnField: this.currentSortConfig.column,
      mode: sortMode
    })
    
    // 立即重新渲染
    this.refresh()
  }
  
  // 清除排序
  clearSort(): void {
    this.currentSortConfig = {
      column: null,
      direction: null
    }
    
    // 恢复原始顺序
    this.dataManager.restoreOriginalOrder()
    
    // 更新渲染器
    if (this.renderer) {
      this.renderer.setSortConfig(null, null)
    }
    
    // 触发排序事件
    this.emit(EventType.Sort, {
      column: null,
      direction: null
    })
    
    this.refresh()
  }
  
  // 获取当前排序配置
  getSortConfig(): { column: string | null; direction: 'asc' | 'desc' | null } {
    return { ...this.currentSortConfig }
  }

  // 设置排序配置（用于远程排序）
  setSortConfig(column: string | null, direction: 'asc' | 'desc' | null): void {
    // 保存到实例属性
    this.currentSortConfig = { column, direction }
    
    // 只更新渲染器的排序配置，不改变数据
    if (this.renderer) {
      this.renderer.setSortConfig(column, direction)
    }
    
    // 刷新显示
    this.refresh()
  }

  // ===== 过滤功能 =====
  
  // 设置列过滤
  setColumnFilter(
    columnField: string, 
    value: any, 
    operator?: 'equals' | 'contains' | 'startsWith' | 'endsWith' | 'gt' | 'gte' | 'lt' | 'lte' | 'between' | 'in' | 'notIn' | 'custom',
    filterFn?: (value: any, filterValue: any) => boolean
  ): void {
    const column = this.columns.find(col => col.field === columnField)
    if (!column || column.filterable === false) return
    
    // 执行过滤
    this.dataManager.setColumnFilter(columnField, value, operator, filterFn)
    
    // 触发过滤事件
    this.emit(EventType.Filter, {
      column: columnField,
      value: value,
      operator: operator
    })
    
    // 重新渲染
    this.refresh()
  }
  
  // 清除列过滤
  clearColumnFilter(columnField: string): void {
    this.dataManager.clearColumnFilter(columnField)
    
    // 触发过滤事件
    this.emit(EventType.Filter, {
      column: columnField,
      value: null,
      operator: null
    })
    
    this.refresh()
  }
  
  // 清除所有过滤
  clearAllFilters(): void {
    this.dataManager.clearAllFilters()
    
    // 触发过滤事件
    this.emit(EventType.Filter, {
      column: null,
      value: null,
      operator: null
    })
    
    this.refresh()
  }
  
  // 获取当前过滤配置
  getFilterConfig(): Record<string, any> {
    return this.dataManager.getFilterConfig()
  }
  
  // ===== 搜索功能 =====
  
  // 全局搜索
  search(searchText: string, options?: {
    columns?: string[]
    caseSensitive?: boolean
    wholeWord?: boolean
    regex?: boolean
  }): CellPosition[] {
    const results: CellPosition[] = []
    const rowCount = this.dataManager.getRowCount()
    const searchColumns = options?.columns || this.columns.map(col => col.field)
    
    // 准备搜索模式
    let searchPattern: RegExp | null = null
    if (options?.regex) {
      try {
        searchPattern = new RegExp(searchText, options.caseSensitive ? 'g' : 'gi')
      } catch (e) {
        console.error('Invalid regex pattern:', e)
        return []
      }
    }
    
    // 搜索数据
    for (let row = 0; row < rowCount; row++) {
      for (let col = 0; col < this.columns.length; col++) {
        const column = this.columns[col]
        if (!searchColumns.includes(column.field)) continue
        
        const value = this.dataManager.getCellValue(row, column.field)
        if (value == null) continue
        
        const cellText = String(value)
        let match = false
        
        if (searchPattern) {
          match = searchPattern.test(cellText)
        } else {
          const searchStr = options?.caseSensitive ? searchText : searchText.toLowerCase()
          const cellStr = options?.caseSensitive ? cellText : cellText.toLowerCase()
          
          if (options?.wholeWord) {
            const wordBoundary = '\\b'
            const regex = new RegExp(`${wordBoundary}${searchStr}${wordBoundary}`, options.caseSensitive ? 'g' : 'gi')
            match = regex.test(cellText)
          } else {
            match = cellStr.includes(searchStr)
          }
        }
        
        if (match) {
          results.push({ row, col })
        }
      }
    }
    
    return results
  }
  
  // 高亮搜索结果
  highlightSearchResults(results: CellPosition[]): void {
    // TODO: 实现搜索结果高亮
    this.render()
  }

  // 触发事件
  private emit(eventType: EventType, data: any): void {
    // 使用事件管理器的emit方法，如果是私有的，则直接触发处理器
    const handlers = this.eventHandlers.get(eventType)
    if (handlers) {
      handlers.forEach(handler => handler(data))
    }
  }

  // 更新显示选项
  updateDisplayOptions(options: { showRowNumber?: boolean; showGridLines?: boolean }): void {
    if (options.showRowNumber !== undefined) {
      this.options.showRowNumber = options.showRowNumber
      this.renderer.toggleRowNumbers(options.showRowNumber)
    }
    
    if (options.showGridLines !== undefined) {
      this.options.showGridLines = options.showGridLines
      this.renderer.toggleGridLines(options.showGridLines)
    }
    
    this.refresh()
  }
  
  // 设置分页信息
  setPageInfo(currentPage: number, pageSize: number): void {
    if ('setPageInfo' in this.renderer) {
      this.renderer.setPageInfo(currentPage, pageSize)
      this.refresh()
    }
  }
  
  // 更新ARIA属性
  private updateAriaAttributes(): void {
    this.canvas.setAttribute('aria-rowcount', String(this.dataManager.getRowCount()))
    this.canvas.setAttribute('aria-colcount', String(this.columns.length))
    
    // 更新当前单元格信息
    const selection = this.eventManager.getSelection()
    if (selection.currentCell) {
      this.canvas.setAttribute('aria-activedescendant', `cell-${selection.currentCell.row}-${selection.currentCell.col}`)
    }
  }

  // 确保单元格完全可见
  private ensureCellVisible(row: number, col: number): void {
    const column = this.columns[col]
    const cellWidth = column.width || 100
    const cellHeight = this.scrollManager.getRowHeight(row)
    
    const scrollPos = this.scrollManager.getScrollPosition()
    const containerSize = this.scrollManager.getContainerSize()
    const headerHeight = this.scrollManager.getHeaderHeight()
    const rowNumberWidth = this.options.showRowNumber ? this.renderer['rowNumberWidth'] : 0
    const scrollbarWidth = this.scrollManager.getScrollbarWidth()
    const scrollbarInfo = this.scrollManager.getScrollbarInfo()
    
    // 添加一些边距，确保单元格周围有一些空间
    const margin = 5
    
    // 计算单元格的实际位置（相对于内容区域，不是视口）
    let cellTop = 0
    for (let i = 0; i < row; i++) {
      cellTop += this.scrollManager.getRowHeight(i)
    }
    
    let cellLeft = 0
    for (let i = 0; i < col; i++) {
      cellLeft += (this.columns[i].width || 100)
    }
    
    // 计算可视区域（考虑表头、行号列和滚动条）
    const visibleLeft = margin
    const visibleTop = headerHeight + margin
    const visibleRight = containerSize.width - (scrollbarInfo.vertical.visible ? scrollbarWidth : 0) - margin
    const visibleBottom = containerSize.height - (scrollbarInfo.horizontal.visible ? scrollbarWidth : 0) - margin
    const visibleWidth = visibleRight - visibleLeft - rowNumberWidth
    const visibleHeight = visibleBottom - visibleTop
    
    // 计算单元格在内容区域的边界
    const cellRight = cellLeft + cellWidth
    const cellBottom = cellTop + cellHeight
    
    let newScrollLeft = scrollPos.scrollLeft
    let newScrollTop = scrollPos.scrollTop
    
    // 水平滚动调整
    if (cellLeft < scrollPos.scrollLeft + margin) {
      // 单元格在左边界外
      newScrollLeft = Math.max(0, cellLeft - margin)
    } else if (cellRight > scrollPos.scrollLeft + visibleWidth) {
      // 单元格在右边界外
      const contentSize = this.scrollManager.getContentSize()
      const maxScrollLeft = Math.max(0, contentSize.width - containerSize.width)
      newScrollLeft = Math.min(
        cellRight - visibleWidth + margin,
        maxScrollLeft
      )
    }
    
    // 垂直滚动调整
    if (cellTop < scrollPos.scrollTop + margin) {
      // 单元格在上边界外
      newScrollTop = Math.max(0, cellTop - margin)
    } else if (cellBottom > scrollPos.scrollTop + visibleHeight) {
      // 单元格在下边界外
      const contentSize = this.scrollManager.getContentSize()
      const maxScrollTop = Math.max(0, contentSize.height - containerSize.height)
      newScrollTop = Math.min(
        cellBottom - visibleHeight + margin,
        maxScrollTop
      )
    }
    
    // 如果需要滚动，执行滚动
    if (newScrollLeft !== scrollPos.scrollLeft || newScrollTop !== scrollPos.scrollTop) {
      this.scrollManager.setScrollPosition(newScrollLeft, newScrollTop)
      this.render()
    }
  }
} 